home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 3: Developer Tools / Linux Cubed Series 3 - Developer Tools.iso / devel / lang / ada / adaed-1.11 / adaed-1 / Adaed-1.11.0a / load.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-02-07  |  15.0 KB  |  520 lines

  1. /*
  2.  * Copyright (C) 1985-1992  New York University
  3.  * 
  4.  * This file is part of the Ada/Ed-C system.  See the Ada/Ed README file for
  5.  * warranty (none) and distribution info and also the GNU General Public
  6.  * License for more details.
  7.  
  8.  */
  9.  
  10. /* load.c - procedures to load to libraries and axq files */
  11.  
  12. #include <stdlib.h>
  13. #include <stdio.h>
  14. #include <string.h>
  15. #include "config.h"
  16. #include "int.h"
  17. #include "segment.h"
  18. #include "slot.h"
  19. #include "ivars.h"
  20. #include "ifile.h"
  21. #ifdef vms
  22. /*
  23. #include "adaexec.h"
  24. #include descrip
  25. */
  26. #endif
  27. #include "miscprots.h"
  28. #include "libfprots.h"
  29. #include "axqrprots.h"
  30. #include "loadprots.h"
  31.  
  32. static void init_predef();
  33. static void init_library(IFILE *, char *);
  34. static char *unit_name_name(char *);
  35. static int *unit_list_new();
  36. static void unit_list_copy(int *, int *);
  37. static int unit_list_next(int *);
  38. static int in_loaded(char *);
  39.  
  40. /* Various sets and maps in the SETL version are represented using
  41.  * strings in the C version. This is possible since they all have as
  42.  * their domain unit_numbers, and the total number of unit_numbers is
  43.  * known before these are needed. The initial values of these items
  44.  * are set by 
  45.  *    s = unit_list_new(). 
  46.  * Once defined, s[i] is YES if unit i is in the set, NO otherwise.
  47.  * These sets are kept as a vector of (short) integers, with the
  48.  * first (zeroth) element giving the number of elements, in much the
  49.  * way is tuples are represented in the other parts of the compiler.
  50.  */
  51. #define YES 1
  52. #define NO 0
  53.  
  54. static char  **file_number;
  55. static int  **PRECEDES_MAP;
  56. static char  **unit_names;
  57. static int     unit_count;
  58. static int   interfaced_unit = 0;
  59. static int   obsolete_error = FALSE;
  60.  
  61. /* The following struct is used main a list of the units actually loaded. */
  62. struct axq_loaded {
  63.     struct axq_loaded  *loaded_next;
  64.     char   *loaded_name;
  65. };
  66. static struct axq_loaded  *ll_head; /* pointer to head of list */
  67.  
  68. static void init_predef()                                        /*;init_predef*/
  69. {
  70.     int     i;
  71.     static char *predef_units[] = {
  72.         "spSYSTEM", "spIO_EXCEPTIONS", "spSEQUENTIAL_IO",
  73.         "boSEQUENTIAL_IO", "spDIRECT_IO", "boDIRECT_IO",
  74.         "spTEXT_IO", "boTEXT_IO", "spCALENDAR", "boCALENDAR",
  75.         "ssUNCHECKED_DEALLOCATION", "suUNCHECKED_DEALLOCATION",
  76.         "ssUNCHECKED_CONVERSION", "suUNCHECKED_CONVERSION"
  77. #ifdef PREDEF_PC
  78.         ,"spTEXT_IO_TYPES", "spTIO_MANAGE", "boTIO_MANAGE",
  79.         "spTIO_DEFAULT", "boTIO_DEFAULT", "spTIO_LENGTH",
  80.         "boTIO_LENGTH", "spTIO_LAYOUT", "boTIO_LAYOUT",
  81.         "spTIO_STRING", "boTIO_STRING", 
  82.         "spTIO_INTEGER", "boTIO_INTEGER",
  83.         "spTIO_FLOAT", "boTIO_FLOAT",
  84.         "spTIO_FIXED", "boTIO_FIXED",
  85.         "spTIO_ENUMERATION", "boTIO_ENUMERATION",
  86.         "spINTEGER_TEXT_IO", "boINTEGER_TEXT_IO", 
  87.         "spFLOAT_TEXT_IO", "boFLOAT_TEXT_IO"
  88. #endif
  89.     };
  90.  
  91.     /* Set values for unit_names, file_number and PRECEDES information for
  92.      * predefined compilation units, since they do not appear in any library
  93.      */
  94.     /* allocate unit names - recalling it is ones origin */
  95. #ifdef PREDEF_PC
  96.     unit_count = 37;
  97. #else 
  98.     unit_count = 14;
  99. #endif
  100.     unit_names = (char **) emalloct((unit_count + 1) * sizeof(char *),
  101.       "unit_names");
  102.     PRECEDES_MAP = (int **) emalloct(sizeof(char **) *(unit_count + 1),
  103.       "precedes_map");
  104.     PRECEDES_MAP[0] =  (int *) unit_count;
  105.     file_number = (char **) emalloct(sizeof(char **) *(unit_count + 1),
  106.       "file_number");
  107.     for (i = 1; i <= unit_count; i++) {
  108.         unit_names[i] = predef_units[i - 1];
  109.         file_number[i] = "0";
  110.         PRECEDES_MAP[i] = unit_list_new();
  111.     }
  112. }
  113.  
  114. void load_lib(char *filename, IFILE *libfile, Axq axq, char *main_unit,
  115.   char **argv)                                                    /*;load_lib*/
  116. {
  117.     /* This procedure looks for the main unit
  118.      * and loads it, together with all units on which it depends directly
  119.      * or indirectly. Dependences are taken from map precedes.
  120.      */
  121.  
  122.     struct axq_loaded  *ll_new;
  123.     int   *main_units, *bound_units, *new_main_units, *to_read, *precedes;
  124.     int       unitn;
  125.     int     i, name, pi;
  126.     int     is_predef_unit;
  127.     int     nmain_units;
  128.     char   *idle_task_name, *unit_file;
  129.     IFILE * axqfile;
  130.     char    exename[100];
  131.     char   *PREDEFNAME;
  132.     char   *file_name, *l_name, *t_name;
  133. #ifdef vms
  134.     struct      dsc$descriptor_s string_desc;
  135. #endif
  136.  
  137.     ll_head = (struct axq_loaded   *) 0; /* Initially, no files loaded */
  138.     init_library(libfile,main_unit);
  139.     main_units = unit_list_new();
  140.     bound_units = unit_list_new();
  141.     for (i = 1; i <= unit_count; i++) {
  142.         if (streq(unit_name_type(unit_names[i]), "ma"))
  143.             main_units[i] = YES;
  144.     }
  145.     if (main_unit != (char *) 0) {
  146.         /* main_units := {[x,y]: [x,y] in main_units 
  147.          *        | y = '_'+MAINUNIT+'_idle_task'}; 
  148.          */
  149.         idle_task_name = strjoin(main_unit, "_idle_task");
  150.         for (name = 1; name <= unit_count; name++) {
  151.             if (main_units[name] == NO)
  152.                 continue;
  153.             if (streq(idle_task_name, unit_names[name]+2))
  154.                 bound_units[name] = YES;
  155.         }
  156.         unit_list_copy(main_units, bound_units);
  157.     }
  158.     nmain_units = 0;
  159.     for (i = 1; i <= main_units[0]; i++)
  160.         if (main_units[i]) nmain_units++;
  161.     if (nmain_units == 0) {
  162. #ifdef vms
  163.         LIB$SIGNAL(MSG_NOTBOUND);
  164.         exit();
  165. #else
  166.         printf("*** Unbound library, execution not allowed\n");
  167.         exit(RC_ERRORS);
  168. #endif
  169.     }
  170.     else if (nmain_units > 1) {
  171. #ifdef vms
  172.         LIB$SIGNAL(MSG_MANYMAIN);
  173.         LIB$SIGNAL(MSG_SPECIFY);
  174.         for (name = 1; name <= unit_count; name++) {
  175.             if (main_units[name] == NO)
  176.                 continue;
  177.             /* name of the form _xxx_idle_task, print only xxx */
  178.             unit_names[name][strlen(unit_names[name])-10] = '\0';
  179.             string_desc.dsc$w_length = strlen(unit_names[name]+2);
  180.             string_desc.dsc$b_dtype = DSC$K_DTYPE_T;
  181.             string_desc.dsc$b_class = DSC$K_CLASS_S;
  182.             string_desc.dsc$a_pointer = unit_names[name]+2;
  183.             LIB$SIGNAL(MSG_MAIN,1,&string_desc);
  184.         }
  185.         exit();
  186. #else
  187.         printf("*** More than one main program in library\n");
  188.         printf("    Use option: -m(one of the following)\n");
  189.         for (name = 1; name <= unit_count; name++) {
  190.             if (main_units[name] == NO)
  191.                 continue;
  192.             unit_names[name][strlen(unit_names[name])-10] = '\0';
  193.             /* name of the form _xxx_idle_task, print only xxx */
  194.             printf("    %s\n", unit_names[name]+2);
  195.         }
  196.         exit(RC_ERRORS);
  197. #endif
  198.     }
  199.     else {
  200. #ifndef INTERFACE
  201. #ifdef SUPPORT_PRAGMA_INTERFACE
  202.         /* at this point, if the main binding unit is interfaced, we run
  203.          * the executable which has been built with the procedure interface
  204.          */
  205.         if (interfaced_unit != 0) {
  206.             sprintf(exename,"%s%s%s.exe",filename,DIR_DELIMITER,
  207.               file_number[interfaced_unit]);
  208.             execvp(exename,argv);
  209.         }
  210. #endif
  211. #endif
  212.         if (obsolete_error) {
  213.             printf(
  214.               "*** Main binding unit obsolete, please recompile or rebind \n");
  215.             exit(RC_ERRORS);
  216.         }
  217.         to_read = unit_list_new();
  218.         while(unit_list_next(main_units)) {
  219.             for (name = 1; name <= unit_count; name++) {
  220.                 if (main_units[name] == NO)
  221.                     continue;
  222.                 to_read[name] = YES;
  223.             }
  224.             /* main_units := {} +/{ precedes{u} : u in main_units}; */
  225.             new_main_units = unit_list_new();
  226.             /* for name in main_units */
  227.             for (name = 1; name <= unit_count; name++) {
  228.                 if (main_units[name] == NO)
  229.                     continue;
  230.                 precedes = PRECEDES_MAP[name];
  231.                 for (pi = 1; pi <= unit_count; pi++) {
  232.                     if (precedes[pi] == NO)
  233.                         continue;
  234.                     new_main_units[pi] = YES;
  235.                 }
  236.             }
  237.             unit_list_copy(main_units, new_main_units);
  238.         }
  239.         while((unitn = unit_list_next(to_read))) {
  240.             to_read[unitn]  = NO;        /* remove from set */
  241.             if (unitn == 0) {
  242.                 /* junk unit number - binder shouldn't be putting this out */
  243.                 printf("load.c: skipping 0 case\n");
  244.                 continue;
  245.             }
  246.             if (unitn <= unit_count    /* false if "ghost package body" */
  247.             &&(!in_loaded(file_number[unitn]))) {
  248.                 unit_file = (char *) file_number[unitn];
  249.                 file_name = unit_file;
  250.                 is_predef_unit =  streq(unit_file,"0");
  251.                 if (is_predef_unit) {
  252.                     PREDEFNAME = predef_env();
  253.                     l_name = libset(PREDEFNAME); /* use predef library */
  254.                     file_name = "predef";
  255.                 }
  256.                 axqfile = ifopen(file_name, "axq", "r", "a", iot_ais_r, 0);
  257.                 read_axq(axqfile, axq);
  258.                 ifclose(axqfile);
  259.                 if (is_predef_unit)
  260.                     t_name = libset(l_name); /* restore user library */
  261.                 if (!in_loaded(unit_file))
  262.                     ll_new = (struct axq_loaded *)
  263.                       smalloc(sizeof(struct axq_loaded));
  264.                 ll_new->loaded_next = ll_head;
  265.                 ll_new->loaded_name = unit_file;
  266.                 ll_head = ll_new;
  267.             }
  268.         }            /* while */
  269.     }
  270. }
  271.  
  272. static void init_library(IFILE *ifile, char *main_unit)        /*;init_library*/
  273. {
  274.     /*
  275.      * retrieve information from ifile
  276.      */
  277.  
  278.     int     i, j, n, m, unumber,cur_level;
  279.     int        ignore;
  280.     int     punit;
  281.     char   *uname, *aisname;
  282.     int    *precedes;
  283.     char   *main_binding_unit = (char *)0;
  284.     int    units_lib;
  285.     int    is_interfaced,comp_status;
  286.  
  287.     init_predef();
  288.     ll_head = (struct axq_loaded   *) 0;
  289.     if (ifile == (IFILE *) 0) {
  290. #ifdef vms
  291.         LIB$SIGNAL(MSG_LIBRARY);
  292.         exit();
  293. #else
  294.         printf("*** library is empty\n");
  295.         exit(RC_ERRORS);
  296. #endif
  297.     }
  298.     units_lib = getnum(ifile, "lib-unit-count");
  299.     unit_count = getnum(ifile, "lib-unit_num");
  300.     getnum(ifile, "lib-empty-slots"); /* ignore */
  301.     getstr(ifile, "lib-tmp-str");     /* ignore */
  302.     unit_names = (char **) erealloct((char *)unit_names,
  303.       (unit_count+1) * sizeof(char **), "unit_names-re");
  304.  
  305.     file_number = (char **) erealloct((char *)file_number,
  306.         sizeof(char **) *(unit_count+1),"file_number-re");
  307. #ifndef INTERFACE
  308.     if (main_unit != (char *)0) {
  309.         /* a main unit was specified */
  310.         main_binding_unit = strjoin("ma",main_unit);
  311.         main_binding_unit = strjoin(main_binding_unit,"_idle_task");
  312.     }
  313. #endif
  314.     for (i = 1; i <= units_lib; i++) {
  315.         uname = getstr(ifile, "lib-unit-name");
  316.         unumber = getnum(ifile, "lib-unit-number");
  317.         aisname = getstr(ifile, "lib-ais-name");
  318.         getstr(ifile, "comp-date");   /* ignore */
  319.         getnum(ifile, "lib-symbols"); /* ignore */
  320.         getnum(ifile, "lib-nodes");   /* ignore */
  321.         is_interfaced = getnum(ifile, "lib-is-main");
  322. #ifdef SUPPORT_PRAGMA_INTERFACE
  323. #ifndef INTERFACE
  324.         if (main_binding_unit != (char *) 0) {
  325.             /* check is_main (interfaced flag) only for binding unit 
  326.              * corresponding to specified main unit
  327.              */
  328.             if (streq(uname,main_binding_unit) && is_interfaced)
  329.                 interfaced_unit = unumber;
  330.         }
  331.         else {
  332.             /* look at is_main (interfaced flag) for any main binding unit.
  333.              * if there is more that one of these, we will report an error
  334.              * later !!
  335.              */
  336.             if (streq(unit_name_type(uname),"ma") && is_interfaced)
  337.                 interfaced_unit = unumber;
  338.         }
  339. #endif
  340. #endif
  341.         comp_status = getnum(ifile, "lib-status");
  342.         /* verify that main binding unit status is not obsolete */
  343.         /* ignore this field for all other units */
  344.         if (main_binding_unit != (char *) 0) {
  345.             /* check comp_status only for specified main binding unit */
  346.             if (streq(uname,main_binding_unit) && !comp_status)
  347.                 obsolete_error = TRUE;
  348.         }
  349.         else {
  350.             /* if none specified, check for any main binding unit */
  351.             if (streq(unit_name_type(uname),"ma") && !comp_status)
  352.                 obsolete_error = TRUE;
  353.         }
  354.         unit_names[unumber] = strjoin(uname, "");
  355.         file_number[unumber] = strjoin(aisname, "");
  356.     }
  357.     /* read but ignore stub info */
  358.     n = getnum(ifile, "lib-n");
  359.     for (i = 1; i <= n; i++) {
  360.         uname = getstr(ifile, "lib-unit-name");
  361.         aisname = getstr(ifile, "lib-ais-name");
  362.         ignore = getnum(ifile, "lib-parent");
  363.         cur_level = getnum(ifile, "lib-cur_level");
  364.         m = getnum(ifile, "stub-file-size");
  365.         for (j = 1; j <= m; j++)
  366.             ignore = getnum(ifile, "stub-file");
  367.     }
  368.  
  369.     PRECEDES_MAP = (int **) emalloct(sizeof(char **) *(unit_count + 1),
  370.       "precedes_map");
  371.     for (i = 1; i <= unit_count; i++)
  372.         PRECEDES_MAP[i] = unit_list_new();
  373.     n = getnum(ifile, "precedes-map-size");
  374.     for (i = 1; i <= n; i += 2) {
  375.         unumber = getnum(ifile, "precedes-map-ent");
  376.         m = getnum(ifile, "precedes-map-set-size");
  377.         precedes = unit_list_new();
  378.         for (j = 1; j <= m; j++) {
  379.             punit = getnum(ifile, "precedes-map-ent");
  380.             precedes[punit] = YES;
  381.         }
  382.         if (unumber==0) chaos("unit number zero");
  383.         PRECEDES_MAP[unumber] = precedes;
  384.     }
  385.     return;
  386. }
  387.  
  388. static char *unit_name_name(char *u)                        /*;unit_name_name*/
  389. {
  390.     int     n;
  391.     char   *s1, *s2;
  392.  
  393.     n = strlen(u);
  394.     if (n <= 2)
  395.         return (char *) 0;
  396.  
  397.     s1 = u + 2;            /* point to start of name */
  398.     s2 = strchr(s1, '.');    /* look for dot after first name */
  399.     if (s2 == (char *) 0)    /* if no dot take rest of string */
  400.         s2 = u + n;        /* find end */
  401.     n = s2 - s1;
  402.     s2 = smalloc((unsigned) n + 1);
  403.     strncpy(s2, s1, n);
  404.     s2[n] = '\0';        /* terminate result */
  405.     return (s2);
  406. }
  407.  
  408. long load_slots(char *fname, IFILE **ifile, Axq axq)            /*;load_slots*/
  409. {
  410.     IFILE  *AXQFILE;
  411.     Slot slot;
  412.     int     i;
  413.     long    cde_pos;
  414.  
  415.     AXQFILE = ifopen(LIBFILENAME, "", "r", "l", iot_lib_r, 0);
  416.     cde_pos = get_cde_slots(AXQFILE, axq);
  417.     *ifile = AXQFILE;        /* store file pointer */
  418.  
  419.     code_slots_dim = axq->axq_code_segments_dim;
  420.     data_slots_dim = axq->axq_data_segments_dim;
  421.     exception_slots_dim = axq->axq_exception_slots_dim;
  422.     code_slots = (char **) ecalloct(code_slots_dim, sizeof(char *),
  423.       "code_slots");
  424.     data_slots = (char **) ecalloct(data_slots_dim, sizeof(char *),
  425.       "data_slots");
  426.     exception_slots = (char **) ecalloct(exception_slots_dim, sizeof(char *),
  427.       "exception_slots");
  428.     /* now get names from list and put in proper place */
  429.     for (i = 1; i < axq->axq_code_slots_dim; i++) {
  430.         slot = axq->axq_code_slots[i];
  431.         if (slot == (Slot) 0)
  432.             continue;
  433.         if (slot->slot_number == 0)
  434.             continue;
  435.         code_slots[slot->slot_number] = slot->slot_name;
  436.     }
  437.     for (i = 1; i < axq->axq_data_slots_dim; i++) {
  438.         slot = axq->axq_data_slots[i];
  439.         if (slot == (Slot) 0)
  440.             continue;
  441.         if (slot->slot_number == 0)
  442.             continue;
  443.         data_slots[slot->slot_number] = slot->slot_name;
  444.     }
  445.     for (i = 1; i < axq->axq_exception_slots_dim; i++) {
  446.         slot = axq->axq_exception_slots[i];
  447.         if (slot == (Slot) 0)
  448.             continue;
  449.         if (slot->slot_number == 0)
  450.             continue;
  451.         exception_slots[slot->slot_number] = slot->slot_name;
  452.     }
  453.     code_segments_dim = axq->axq_code_segments_dim;
  454.     code_segments = (char **) ecalloct(axq->axq_code_segments_dim, 
  455.       sizeof(char *),"code_segments");
  456.     code_seglen = (int *) ecalloct(axq->axq_code_segments_dim, sizeof(int),
  457.       "code_seglen");
  458.     axq->axq_code_segments = code_segments;
  459.     axq->axq_code_seglen = code_seglen;
  460.     data_segments_dim = axq->axq_data_segments_dim;
  461.     data_segments = (int **) ecalloct(axq->axq_data_segments_dim, 
  462.       sizeof(char *),"data_segments");
  463.     data_seglen = (int *) ecalloct(axq->axq_data_segments_dim, sizeof(int),
  464.       "data_seglen");
  465.     axq->axq_data_segments = data_segments;
  466.     axq->axq_data_seglen = data_seglen;
  467.  
  468.     if ((*ifile)->fh_trace) {
  469.         for (i = 1; i < axq->axq_code_segments_dim; i++)
  470.             printf("code_segment %2d length %8d\n",i,code_seglen[i]);
  471.         for (i = 1; i < axq->axq_data_segments_dim; i++)
  472.             printf("data_segment %2d length %8d\n",i,data_seglen[i]);
  473.     }
  474.     return cde_pos;
  475. }
  476.  
  477. static int *unit_list_new()                                 /*;unit_list_new*/
  478. {
  479.     int    *u;
  480.  
  481.     u = (int *) smalloc(sizeof(int) * (unit_count + 1));
  482.     u[0] = unit_count;
  483.     for (i = 1; i <= unit_count; i++)
  484.         u[i] = NO;
  485.     return u;
  486. }
  487.  
  488. static void unit_list_copy(int *u1, int *u2)             /*;unit_list_copy*/
  489. {
  490.     int n,i;
  491.  
  492.     n = u1[0];
  493.     if (n != u2[0])
  494.         chaos("unit_copy sizes differ");
  495.     for (i = 1; i <= n; i++)
  496.         u1[i] = u2[i];
  497. }
  498.  
  499. static int unit_list_next(int *u1)                        /*;unit_list_next*/
  500. {
  501.     int i,n;
  502.  
  503.     n = u1[0];
  504.     for (i = 1; i <= n; i++)
  505.         if (u1[i]) return i;
  506.     return 0;
  507. }
  508.  
  509. static int in_loaded(char *str)                                /*;in_loaded*/
  510. {
  511.     /* test to see if named file has been loaded */
  512.     struct axq_loaded  *p;
  513.  
  514.     for (p = ll_head; p != (struct axq_loaded  *) 0; p = p->loaded_next)
  515.         if (streq(str, p->loaded_name))
  516.             return TRUE;
  517.  
  518.     return FALSE;
  519. }
  520.